﻿using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;

namespace winS.UnityEditor.UIElement
{
    /// <summary>
    /// 单选按钮组.
    /// 在该组下, 一次只能选择一个单选按钮
    /// </summary>
    public class RadioButtonGroup<T> : EditorField<T>
    {
        public VisualElement group { get; private set; }

        private readonly List<RadioButton> radioButtonList = new List<RadioButton>();

        internal RadioButtonGroup(ElementFactory elementFactory) : base(elementFactory)
        {
            Add(group = EditorElementUtility.elementFactory.CreateEditorElement());
            group.style.flexGrow = 1f;
            style.flexDirection = group.style.flexDirection = FlexDirection.Row;
        }

        public void AddChoice(string name, T value)
        {
            RadioButton radioButton = new RadioButton(name, value);
            radioButton.onEnable += RadioButtonEnableCallback;
            radioButtonList.Add(radioButton);
            group.Add(radioButton);
        }

        public override void SetValueWithoutNotify(T value)
        {
            base.SetValueWithoutNotify(value);
            EnableRadioButtonByValue(value);
        }

        protected override void SetValue(T value)
        {
            base.SetValue(value);
            EnableRadioButtonByValue(value);
        }

        private void RadioButtonEnableCallback(T value)
        {
            SetValue(value);
        }
        private void EnableRadioButtonByValue(T value)
        {
            foreach (var radioButton in radioButtonList)
            {
                if (radioButton.value.Equals(value)) radioButton.EnableWithoutNotify();
                else radioButton.Disable();
            }
        }

        /// <summary>
        /// 单选按钮
        /// </summary>
        public class RadioButton : VisualElement
        {
            public static readonly Color defaultCapColor = ColorLevelUtility.GetColor(18);
            public static readonly Color defaultBorderColor = ColorLevelUtility.GetColor(3);
            public static readonly Color defaultBackgroundColor = ColorLevelUtility.GetColor(4);

            public event Action<T> onEnable;

            public bool isEnable { get; private set; }

            public readonly T value;

            private readonly EditorElement box;
            private readonly VisualElement cap;

            public RadioButton(string name, T value)
            {
                this.value = value;
                style.alignItems = Align.Center;
                style.flexDirection = FlexDirection.Row;

                Add(box = EditorElementUtility.elementFactory.CreateEditorElementWithName("按钮框"));
                box.style.SetBorder(defaultBorderColor, 1f, 6f);
                box.style.alignItems = Align.Center;
                box.style.justifyContent = Justify.Center;
                box.style.height = box.style.width = 12f;
                box.style.SetBackgroundColor(defaultBackgroundColor);
                EditorElementUtility.ApplyFocusElementStyle(box, defaultBorderColor);

                box.Add(cap = EditorElementUtility.elementFactory.CreateEditorElementWithName("盖子"));
                cap.style.height = cap.style.width = 6f;
                cap.style.SetScale(0f);
                cap.style.SetBorderRadius(3f);
                cap.style.SetBackgroundColor(defaultCapColor);
                cap.style.SetTransition("scale", 0.1f);

                Label label = EditorElementUtility.elementFactory.CreateLabel(name);
                label.style.marginLeft = 4f;
                label.style.marginRight = 6f;
                Add(label);

                EditorElementUtility.RegisterClickEvent(this, Enable);
            }

            public void Enable()
            {
                if (isEnable) return;
                isEnable = true;
                cap.style.SetScale(1f);
                onEnable?.Invoke(value);
            }

            public void Disable()
            {
                if (!isEnable) return;
                isEnable = false;
                cap.style.SetScale(0f);
            }
            public void EnableWithoutNotify()
            {
                if (isEnable) return;
                isEnable = true;
                cap.style.SetScale(1f);
            }
        }
    }
}